<template>
  <div class="containers">
    <div ref="canvas" class="canvas" />
    <div id="js-properties-panel" class="panel" />
    <el-button-group class="buttons">

      <el-button size="mini" type="primary" :disabled="this.saveStatus">
        <a ref="saveDiagram" href="javascript:">下载</a>
      </el-button>
      <el-button size="mini" type="primary">
        <a ref="saveSvg" href="javascript:">取消</a>
      </el-button>
    </el-button-group>
  </div>
</template>

<script>
// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
// xml字符串
import {
  xmlStr
} from './leaveProcess.bpmn' // 这里是直接引用了xml字符串

import propertiesPanelModule from 'bpmn-js-properties-panel'
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import customTranslate from './customTranslate'

export default {
  name: '',
  components: {},
  data() {
    return {
      // bpmn建模器
      bpmnModeler: null,
      container: null,
      canvas: null,
      saveStatus: false,
      bpmnStr: ''

    }
  },
  // 生命周期 - 创建完成（可以访问当前this实例）
  created() {
  },
  // 生命周期 - 载入后, Vue 实例挂载到实际的 DOM 操作完成，一般在该过程进行 Ajax 交互
  mounted() {
    this.init()
  },
  methods: {
    init() {
      this.initBpmn()
    },
    initBpmn() {
      const customTranslateModule = {
        translate: ['value', customTranslate]
      }
      // 获取到属性ref为“canvas”的dom节点
      const canvas = this.$refs.canvas
      // 建模
      this.bpmnModeler = new BpmnModeler({
        container: canvas,
        // 添加控制板
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          // 汉化
          customTranslateModule,
          // 左边工具栏以及节点
          propertiesProviderModule,
          // 右边的属性栏
          propertiesPanelModule
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })
      this.createNewDiagram()
    },
    // 将字符串转换成图显示出来
    createNewDiagram() {
      this.bpmnModeler.importXML(xmlStr, (err) => {
        if (err) {
          console.error(err)
        } else {
          // 渲染成功之后的业务代码
          this.success()
        }
      })
    },
    success() {
      // console.log('创建成功!')
      console.log('创建成功!')
      this.addBpmnListener()
      this.addModelerListener()
      // 渲染已完成节点
    },
    addModelerListener() {
      // 监听 modeler
      const bpmnjs = this.bpmnModeler
      const that = this
      // 'shape.removed'
      const events = ['shape.added', 'shape.move.end', 'connect.end', 'connection.create', 'connection.move']
      events.forEach(function(event) {
        that.bpmnModeler.on(event, e => {
          console.log(event, e)
          var elementRegistry = bpmnjs.get('elementRegistry')
          var shape = e.element ? elementRegistry.get(e.element.id) : e.shape
          console.log(shape)
        })
      })
    },
    // 添加绑定事件
    addBpmnListener() {
      const that = this
      // 获取a标签dom节点
      const downloadLink = this.$refs.saveDiagram
      const downloadSvgLink = this.$refs.saveSvg
      // 给图绑定事件，当图有发生改变就会触发这个事件
      this.bpmnModeler.on('commandStack.changed', function() {
        that.saveSVG(function(err, svg) {
          that.setEncoded(downloadSvgLink, 'diagram.svg', err ? null : svg)
        })
        that.saveDiagram(function(err, xml) {
          that.setEncoded(downloadLink, 'diagram.bpmn', err ? null : xml)
        })
      })
    },
    // 当图发生改变的时候会调用这个函数，这个data就是图的xml
    setEncoded(link, name, data) {
      // 把xml转换为URI，下载要用到的
      const encodedData = encodeURIComponent(data)
      // 下载图的具体操作,改变a的属性，className令a标签可点击，href令能下载，download是下载的文件的名字
      const xmlFile = new File([data], 'test.bpmn')
      if (data) {
        link.className = 'active'
        link.href = 'data:application/bpmn20-xml;charset=UTF-8,' + encodedData
        link.download = name
      }
      this.bpmnStr = data
    },
    // 下载为SVG格式,done是个函数，调用的时候传入的
    saveSVG(done) {
      // 把传入的done再传给bpmn原型的saveSVG函数调用
      this.bpmnModeler.saveSVG(done)
    },
    // 下载为bpmn格式,done是个函数，调用的时候传入的
    saveDiagram(done) {
      // 把传入的done再传给bpmn原型的saveXML函数调用
      this.bpmnModeler.saveXML({ format: true }, function(err, xml) {
        done(err, xml)
      })
    }
  }
}
</script>

<style scoped>
  .containers {
    background-color: #ffffff;
    width: 100%;
    height: calc(100vh - 52px);
  }

  .canvas {
    width: 100%;
    height: 100%;
  }

  .panel {
    position: absolute;
    right: 0;
    top: 0;
    width: 300px;
  }

  .loading {
    font-size: 26px;
  }

  .buttons {
    position: absolute;
    left: 20px;
    bottom: 50px;
  }

  .buttons li {
    display: inline-block;
    margin: 5px;
  }

  .buttons li a {
    color: #999;
    background: #eee;
    cursor: not-allowed;
    padding: 8px;
    border: 1px solid #ccc;
    text-decoration: none;
  }

  .buttons li a.active {
    color: #333;
    background: #fff;
    cursor: pointer;
  }

  .el-form-item--medium .el-form-item__content, .el-form-item--medium .el-form-item__label {
    line-height: 36px;
  }

  .el-form--inline .el-form-item__content {
    display: inline-block;
    vertical-align: top;
  }

  .el-form-item--medium .el-form-item__content {
    line-height: 36px;
  }

  .el-form--inline .el-form-item__content {
    display: inline-block;
    vertical-align: top;
  }

  .el-form-item__content {
    line-height: 40px;
    position: relative;
    font-size: 14px;
  }

  .el-form-item__content {
    line-height: 40px;
    position: relative;
    font-size: 14px;
  }
</style>
